import {Injectable} from '@nestjs/common';
import {InjectRepository} from '@nestjs/typeorm';
import {Repository} from 'typeorm';
import {SurveyEntity} from '../entities/Survey.entity';
import {ResponseEntity} from '../entities/Response.entity';
import {OptionEntity} from '../entities/Option.entity';


@Injectable()
export class SurveyService {

  constructor(
    @InjectRepository(OptionEntity)
    private readonly optionRepository: Repository<OptionEntity>,
    @InjectRepository(SurveyEntity)
    private readonly surveyRepository: Repository<SurveyEntity>,
    @InjectRepository(ResponseEntity)
    private readonly responseRepository: Repository<ResponseEntity>,
  ) {
  }


  /**
   * 查询问卷和问卷问题
   * @param surveyId 问卷id
   */
  async findSurveyWithQuestionsAndOptions(surveyId: string) {
    if (!surveyId) {
      throw new Error('请填写正确的surveyId');
    }

    try {


      const survey = await this.surveyRepository.findOne({
        where: {id: surveyId},
        relations: [
          'questions', // 从Survey到SurveyQuestion的关联
          'questions.question', // 从SurveyQuestion到Question的关联
          'questions.question.options', // 从Question到Option的关联
        ],
      });


      let totalSubmissions = 0;

      // 手动排序
      if (survey && survey.questions) {
        // 根据surveyOrder字段排序
        survey.questions.sort((a, b) => a.surveyOrder - b.surveyOrder);

        // 对每个问题的选项按照选项ID进行排序
        for (const question of survey.questions) {
          question.question.options.sort((a, b) => parseInt(a.id) - parseInt(b.id));

          // 添加计算每个问题的总提交数
          totalSubmissions = await this.responseRepository.count({where: {QuestionId: question.question.id}});
        }

        survey.totalSubmissions = totalSubmissions;
      }

      return survey;
    } catch (error) {
      // 异常处理
      console.error('查找调查时出错:', error);
      throw new Error('查找问卷时出错或问卷不存在');
    }
  }

  /**
   * 保存问卷
   * @param responses 回答
   * @param SurveyId 问卷id
   * @param RespondentId  填写者id
   */
  async saveSurvey(responses: ResponseEntity[], SurveyId: string, RespondentId: string) {

    if (!SurveyId || !RespondentId) {
      throw new Error('surveyId或respondentId不存在');
    }

    // 检查数据库中是否已经存在相同问卷ID和相同填写者ID的记录
    const existingResponse = await this.responseRepository.findOne({
      where: {SurveyId, RespondentId},
    });

    // 如果已经存在相同问卷ID和相同填写者ID的记录，则返回相应的提示消息
    if (existingResponse) {
      throw new Error('您已经填写过该调查表了，请勿重复提交!');
    }

    // 用于存储所有异步操作的 Promise
    const promises: any[] = [];

    // 使用Map缓存选项对象，以减少数据库查询
    const optionsMap: { [key: string]: OptionEntity } = {};

    await Promise.all(responses.map(async (response) => {
      const newResponse = new ResponseEntity();
      Object.assign(newResponse, response);
      promises.push(this.responseRepository.save(newResponse));

      let selectedOption: OptionEntity | null = optionsMap[response.OptionId];
      if (!selectedOption) {
        selectedOption = await this.optionRepository.findOne({
          where: {id: response.OptionId},
        });
        if (selectedOption) {
          selectedOption.selectionCount += 1;
          optionsMap[response.OptionId] = selectedOption; // 缓存选项
          promises.push(this.optionRepository.save(selectedOption));
        }
      }
    }));

    // 遍历每个提交的回答
    // for (const response of responses) {
    //   // 创建一个新的实体对象来保存到数据库
    //   const newResponse = new ResponseEntity();
    //   newResponse.SurveyId = response.SurveyId;
    //   newResponse.QuestionId = response.QuestionId;
    //   newResponse.OptionId = response.OptionId;
    //   newResponse.RespondentId = response.RespondentId;
    //   newResponse.ResponseDateTime = response.ResponseDateTime;
    //   promises.push(this.responseRepository.save(newResponse));
    //
    //
    //   // 从数据库中查找与当前响应关联的选项实体
    //   const selectedOption = await this.optionRepository.findOne({
    //     where: {id: response.OptionId}, // 根据选项ID查询
    //   });
    //
    //   // 如果找到了该选项
    //   if (selectedOption) {
    //     // 增加选项的选择计数
    //     selectedOption.selectionCount += 1;
    //
    //     // 将更新后的选项实体保存回数据库
    //     promises.push(this.optionRepository.save(selectedOption)); // 添加到保存操作的Promise队列中
    //   }
    //
    // }


    // 等待所有异步操作完成
    await Promise.all(promises);

    // 更新所有选项的选择占比
    await Promise.all(responses.map(response => this.updateSelectionPercentages(response.QuestionId)));

    // 查询最新的选项对象，包括selectionCount和selectionPercentage
    const newSurvey = await this.findSurveyWithQuestionsAndOptions(SurveyId);

    return {
      message: '提交成功',
      newSurvey,//返回新的数据给前端
    };
  }

  // 更新所有选项的选择占比
  async updateSelectionPercentages(QuestionId: string) {
    // 获取问卷的总提交次数
    let totalSubmissions = await this.responseRepository.count({where: {QuestionId}});

    // 获取所有选项
    let options = await this.optionRepository.find({where: {questionID: QuestionId}});

    // 计算并更新每个选项的选择占比
    for (let option of options) {
      option.selectionPercentage = totalSubmissions > 0 ? (option.selectionCount / totalSubmissions) * 100 : 0;
      await this.optionRepository.save(option);
    }
  }

}
